parser grammar AnalizadorYACCParser;

options {
  language = Java;
  tokenVocab = AnalizadorYACCLexer;
}

@header {package PL.practica7;}



@members{

  boolean flagelse = false;
  int contador = 0;

ArrayList <RecognitionException> errores = new ArrayList<RecognitionException>();

public boolean listaVacia (){
    if (errores.isEmpty()){
      return true;
    }else
      return false;
}

public ArrayList getListaErrores(){return errores;}


@Override
public void reportError (RecognitionException e){
  System.err.println (getErrorMessage(e, getTokenNames()));
  errores.add(e);
}

}


//reglas para hacer mas legible las reglas MAS COMPLEJAS 
  tipo : (INT|CHAR|POINTER|REGISTER|DOUBLE); 
  operadores : MAS|MENOS|SLASH|ASTERISCO;
  identificadores : ASTERISCO? (IDENT |IDENTMAYUS|IDENTMINUS);
  angulos : CERRARANGULO|ABRIRANGULO;
  vector :  (identificadores corchetes);
  corchetes : ABRIRCORCHETE (RANGO |operacion)? CERRARCORCHETE;
  parametros :  CADENA |NUMERO |CARACTER|SIGNAL;
  operadoreslogicos : (OR |AND| ORLOGICO |ANDLOGICO);


yacc : bloque1? SEPARADORBLOQUE bloque2 SEPARADORBLOQUE bloque3?;


//BLOQUE 1 DECLARACIONES Y TOKENS

bloque1 :  bloqueDeclaracion declaraciontoken;
	  //macro : (IDENT CORCHETES)*;
	  bloqueDeclaracion: ABRIRVARIABLES dentro_declaracion CERRARVARIABLES;
	    incluir :  ALMOHADILLA INCLUDE (ABRIRANGULO identificadores) CERRARANGULO;
	    dentro_declaracion : incluir* (definiryacc|declaracionyacc|estructura)*;
	    declaracionyacc : (tipo|INTERVAL) identificadores ((ABRIRPARENTESIS CERRARPARENTESIS)|corchetes)?
                      (COMA  identificadores ((ABRIRPARENTESIS CERRARPARENTESIS)|corchetes)?)* SEPARADOR;
	    definiryacc : ALMOHADILLA DEFINE identificadores tipo;
	    estructura : TYPEDEF STRUCT IDENTMINUS ABRIRLLAVE (declaracionyacc)+  CERRARLLAVE (identificadores|INTERVAL) SEPARADOR;
	 
    
   
    token : PORCENTAJE TOKEN (ABRIRANGULO (IDENT|IDENTMINUS|IDENTMAYUS) CERRARANGULO)? IDENTMAYUS+;
    left : PORCENTAJE LEFT (CARACTER+ | IDENTMAYUS);
    type : PORCENTAJE TYPE (ABRIRANGULO identificadores CERRARANGULO)? IDENTMINUS;
    start : PORCENTAJE START IDENTMINUS;
    union : PORCENTAJE UNION ABRIRLLAVE (declaracionyacc)* CERRARLLAVE;
    declaraciontoken : start? (token|left|union|type)*; 


//BLOQUE 2 REGLAS YACC
  
  
bloque2: reglasyacc+;
  reglasyacc : IDENTMINUS DOSPUNTOS (OR|IDENT|IDENTMAYUS|PORCENTAJE|IDENTMINUS|CARACTER |accion)+ SEPARADOR;
    accion : ABRIRLLAVE (condicionif | ((signaloperations| printf |IDENTMAYUS|IDENTMINUS) SEPARADOR))+ CERRARLLAVE;
    signaloperations : (SIGNAL|vector) ((IGUAL MENOS? (SIGNAL|vector) ((operadores|PORCENTAJE) (SIGNAL|vector))*)+ | (IGUAL llamadafuncion));


    
// BLOQUE 3 CODIGO C

bloque3 : definir* bloqueyylex bloqueinterval ;
   definir : ALMOHADILLA DEFINE identificadores parametros;
   bloqueyylex : YYLEX ABRIRPARENTESIS CERRARPARENTESIS bloqueLlaves;
   bloque : (buclewhile | condicionif |buclefor| ret| reglaelse|  ((asignacion|printf|llamadafuncion |BREAK|CONTINUE) SEPARADOR));
   bloqueLlaves : ABRIRLLAVE  (buclewhile| condicionif| buclefor |reglaelse | ((asignacion|printf|llamadafuncion |BREAK|CONTINUE) SEPARADOR))* ret?  CERRARLLAVE;
  

   buclefor : FOR ABRIRPARENTESIS dentrofor CERRARPARENTESIS (bloque|bloqueLlaves) ;
    incremento : INCREMENTO identificadores | identificadores INCREMENTO;
    decremento : DECREMENTO identificadores | identificadores DECREMENTO;
    dentrofor :  ((asignacion SEPARADOR) | SEPARADOR) condicionfor? SEPARADOR (incremento|decremento)? COMA? asignacion?;
    condicionfor : operacionparen ((angulos IGUAL?)| DISTINTO | IGUAL) identificadores;

    buclewhile : WHILE ABRIRPARENTESIS condiciones CERRARPARENTESIS (bloque| bloqueLlaves);
    condicionif : {contador++;flagelse = true;} IF  ABRIRPARENTESIS condiciones CERRARPARENTESIS (bloque| bloqueLlaves);
       condiciones :  (condicion) ((operadoreslogicos|COMPARACION) (condicion))*;
//       condicionparen : ABRIRPARENTESIS 
//        ((EXCLAMACION identificadores) 
//        |  ( (operacion|operacionparen) (((angulos IGUAL?)| DISTINTO | IGUAL) (operacion|llamadafuncion))*)
//        | (EXCLAMACION? llamadafuncion))
//         CERRARPARENTESIS;
      condicion :   ((EXCLAMACION identificadores)
       | ((operacionparen|operacion) (((angulos IGUAL?)| DISTINTO | IGUAL) (operacionparen|operacion|llamadafuncion))*) 
       | (EXCLAMACION? llamadafuncion) 
       | (incremento|decremento));      
      operacionparen : ABRIRPARENTESIS (((parametros|identificadores) operadores  (identificadores|parametros))|asignacion) CERRARPARENTESIS;
      operacion : ((parametros|identificadores) (operadores  (identificadores|parametros))*);
      llamadafuncion : identificadores ABRIRPARENTESIS ((identificadores|parametros) (COMA (parametros|identificadores))*)? CERRARPARENTESIS;

      reglaelse : {contador--; if (contador == 0) flagelse = false;} ELSE (bloque|bloqueLlaves);
 
  metodo : cabecerafuncion  bloqueLlaves;

    cabecerafuncion : (tipo | VOID) identificadores ABRIRPARENTESIS ((VOID |tipo IDENT) (COMA tipo parametros)*)? CERRARPARENTESIS;
 
    printf :  PRINTF ABRIRPARENTESIS CADENA (COMA (IDENT|IDENTMINUS|IDENTMAYUS|SIGNAL))* CERRARPARENTESIS ;
    asignacion :  declaracion  ((IGUAL (operacion | llamadafuncion)) | (COMA declaracion))*;
    declaracion : (tipo|INTERVAL)? (identificadores|vector) ;
   // (COMA (identificadores|vector))*
    ret : RETORNAR ABRIRPARENTESIS? (identificadores|parametros|llamadafuncion)? CERRARPARENTESIS? SEPARADOR;
    condicionalaritmetico: condicion INTERROGANTE NUMERO DOSPUNTOS NUMERO SEPARADOR; 
    
    cabecerainterval : INTERVAL identificadores ABRIRPARENTESIS (identificadores (COMA identificadores)*)? CERRARPARENTESIS;
    bloqueinterval : (cabecerainterval| bloque|bloqueLlaves)*;
    
    
 